﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Mono.CSharp;
using Xamarin.Forms;

namespace monocsharptest
{
    public partial class MainPage : ContentPage
    {
              public MainPage()
        {
            InitializeComponent();

        }

        void Button_Clicked(System.Object sender, System.EventArgs e)
        {
            //var cc = new CompilerContext(new CompilerSettings(), new ConsoleReportPrinter());
            //var evaluator = new Evaluator(cc);

            //// add assembly references
            ////evaluator.ReferenceAssembly(..);

            //evaluator.Evaluate("1 + 1", out var result, out _);
            //Console.WriteLine(result); // 2

            //evaluator.Run("public class NewClass { public string HelloWorld => \"Hello World\"; }");
            //evaluator.Evaluate("new NewClass().HelloWorld", out result, out _);
            //Console.WriteLine(result); // "Hello World"

            LoadCSharpScript();
        }

        private void LoadCSharpScript()
        {

            string strchess = string.Empty;       
           // string _fileName = Path.Combine(App.CSFile, "Script.cs");
            string _fileName = Path.Combine(App.CSFile, "Script2.cs");
            bool x = File.Exists(_fileName);
            // strchess= File.ReadAllText(_fileName);
            strchess = File.ReadAllText(_fileName);




            var cc = new CompilerContext(new CompilerSettings(), new ConsoleReportPrinter());
            var evaluator = new Evaluator(cc);

            var assembly = Assembly.GetExecutingAssembly();
            var resouces= assembly.GetManifestResourceNames();
            foreach(var resource in resouces)
            {
                if(resource.Contains(".dll"))
                {
                    var stream= assembly.GetManifestResourceStream(resource);
                    var bytes = new byte[stream.Length];
                    stream.Read(bytes, 0, bytes.Length);
                    evaluator.ReferenceAssembly(Assembly.Load(bytes));
                }
            }
        //    evaluator.ReferenceAssembly(typeof(MathNet.Numerics.Sorting).Assembly);

            Stopwatch watch = new Stopwatch();
            watch.Start();
            object result = null;
            object result2 = null;
            //
            // evaluator.Run(strchess);


            //            evaluator.Run(@"using System.Collections.Generic;
            //using System.Diagnostics;
            //using MathNet.Numerics;
            //public class Script
            //{
            //    private int sum;
            //    public int Sum(int a, int b)
            //    {
            //        var list = new List<int> { a, b };       
            //        MathNet.Numerics.Sorting.Sort(list);          
            //        sum += (a + b);
            //        return sum;
            //        }
            //    }");
            evaluator.Run(@"using NCalc;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
public class ScriptOne
{
        public static Dictionary<string, Dictionary<string, int>> finalResult = new Dictionary<string, Dictionary<string, int>>();

        public static Dictionary<string, int> toAdjustLevel = new Dictionary<string, int>();

        public Dictionary<string, Result> final_result = new Dictionary<string, Result>();

        public static List<string> model_codes = new List<string>();

        public static Dictionary<string, CRule> neededRule = new Dictionary<string, CRule>();

        public static Dictionary<string, double> parametersResult = new Dictionary<string, double>();      



        public static bool ConfigureParas(string neededIndexes, string setting_data)
        {
            Dictionary<string, List<string>> neededData = JsonConvert.DeserializeObject<Dictionary<string, List<string>>>(neededIndexes);

            model_codes = neededData[""analysisModels""];

            Dictionary<string, object> settingData = JsonConvert.DeserializeObject<Dictionary<string, object>>(setting_data);

            if (neededRule != null)
            {
                neededRule.Clear();
                toAdjustLevel.Clear();
            }


            foreach (string item in model_codes)
            {
                // neededRule.Add(item, settingData[item]);
                CRule a = JsonConvert.DeserializeObject<CRule>(settingData[item].ToString());
                settingData[item] = a;
                neededRule.Add(item, a);

                // final_result.Add(item, new Result() { });
                toAdjustLevel.Add(item, 0);
            }

            return true;

        }


        public static bool correct_condition(double drowsinessLevel, double sleepStage)
        {
            if (drowsinessLevel > 0 || sleepStage == 1 || sleepStage == 2 || sleepStage == 3 || sleepStage == 0)
            {
                return true;
            }
            return false;
        }


        public static string OneMinuteAnalysis(string value_json)
        {

            parametersResult = new Dictionary<string, double>();

            // 解析  一分钟对应的数据  
            //  Dictionary<string, List<int>> settingDataValue = JsonConvert.DeserializeObject<Dictionary<string, List<int>>(value_json);

            parametersResult.Clear();

            Dictionary<string, List<int>> settingDataValue = JsonConvert.DeserializeObject<Dictionary<string, List<int>>>(value_json);

            string totalStr = settingDataValue.ToString();
            if (totalStr.Contains(""-99""))
            {
                foreach (var item in settingDataValue.Keys)
                {
                    finalResult[item] = new Dictionary<string, int>()
                      {
                    {""score"", -1},
                    {""level"",-1}
                       };
                }
                return finalResult.ToString();
            }
            foreach (var item in settingDataValue.Keys)
            {

                if (item == ""lfnSet"")
                {
                    var var1 = settingDataValue[item].Sum(x => x);
                    var var2 = settingDataValue[item].Count(x => x == -1);
                    var var3 = settingDataValue[item].Count;
                    var var4 = (var1 + var2) / (var3 - var2);
                    parametersResult.Add(""lfn"", var4);
                }
                else if (item == ""drowsinessLevel"" || item == ""sleepStage"")
                {
                    parametersResult.Add(item, settingDataValue[item][settingDataValue[item].Count - 1]);
                }
                else
                {
                    string var5 = item.Replace(""Set"", """");
                    parametersResult.Add(var5, settingDataValue[item].Count(x => x == 1));
                }
                // parametersResult.Add(item,)

            }

            foreach (string itemX in neededRule.Keys)
            {
                CalculateCfactor(itemX, neededRule);
            }

            string json = JsonConvert.SerializeObject(finalResult);

            return json;
        }
        public static List<string> FindItemsWithChar(List<string> lst, string str)
        {
            List<string> result = new List<string>();
            foreach (string item in lst)
            {
                if (item.Contains(str))
                {
                    result.Add(item);
                }
            }
            return result;
        }


        public static double EvaluateFormula(string someIndex, string formula)
        {
            // Evaluate the formula and return the score

            Expression e = new Expression(formula, EvaluateOptions.IgnoreCase);

            foreach (string item in parametersResult.Keys)
            {
                e.Parameters[item] = parametersResult[item];
            }

            var result = e.Evaluate();


            return (double)result;
        }


        public static int AdjustLevel(string formula)
        {
            // Evaluate the formula and return the score

            Expression e = new Expression(formula, EvaluateOptions.IgnoreCase);

            foreach (string item in toAdjustLevel.Keys)
            {
                e.Parameters[item] = toAdjustLevel[item];
            }

            var result = e.Evaluate();


            return (int)result;
        }

        public static void CalculateCfactor(string variable, Dictionary<string, CRule> modelSettingData)
        {
            List<string> correct_result = new List<string>()
                 {
                ""Max(energyStatus - 1, 1)"",
                ""Max(effortLevel - 1, 1)"",
                ""Max(focusOnInvestment - 1, 1)"",
                ""Max(enterprising - 1, 1)"",
                ""Min(easyObedient + 1, 3)"",
                ""Min(emotionManager + 1, 3)"",
                ""Min(fatigueStatus + 2, 5)""
                 };
            double score = EvaluateFormula(variable, modelSettingData[variable].formula);

            score = (double)ModifyScore(score);

            string[] standard = modelSettingData[variable].standard.Split('|');
            string[] result = modelSettingData[variable].result.Split('|');
            int resultLevel = 0;
            for (int i = 0; i < standard.Length; i++)
            {
                if (score <= double.Parse(standard[i]))
                {
                    resultLevel = int.Parse(result[i]);
                    break;
                }
            }
            if (resultLevel == 0)
            {
                resultLevel = int.Parse(result[result.Length - 1]);
            }

            toAdjustLevel[variable] = resultLevel;
            //

            if (correct_condition(parametersResult[""drowsinessLevel""], parametersResult[""sleepStage""]))
            {
                List<string> result2 = FindItemsWithChar(correct_result, variable);
                if (result2.Count > 0)
                {
                    resultLevel = AdjustLevel(result2[0]);
                }
            }

            finalResult[variable] = new Dictionary<string, int>()
              {
            {""score"", (int)score},
            {""level"", resultLevel}
               };

        }

        public static decimal ModifyScore(double score)
        {
            if (score < 0)
            {
                score = 20 - Math.Log(Math.Abs(score) + 1);
            }
            else if (score >= 99)
            {
                score = 90 + Math.Log(score - 99 + 1);
            }
            decimal score_f = Math.Round((decimal)score, 0);
            return score_f;
        }
    }
    public class CRule
    {
        public string standard { get; set; }
        public string result { get; set; }
        public string formula { get; set; }
    }
    public class Result
    {
        public int score { get; set; }
        public int level { get; set; }
    }

");


            string str1 = @"{""effortLevel"": {""standard"": ""50|80"", ""result"": ""1|2|3"", ""formula"": ""(thinking*1+thinkingActivity*1+lowFlow*1+singleMindedness*1+lfn*0.15)*100/16+max(0,(thinking-5)*10)+max(0,(lowFlow-5)*10)+max(0,(singleMindedness-5)*10)""}, ""focusOnInvestment"": {""standard"": ""50|80"", ""result"": ""1|2|3"", ""formula"": ""(lowFlow*2.1+singleMindedness*2.3+midFlow*5+highFlow*8)*100/8+max(0,(singleMindedness-5)*10)""}, ""enterprising"": {""standard"": ""50|80"", ""result"": ""1|2|3"", ""formula"": ""(impatient*3.5+worryTrait*5+crisisSense*0.8+thinkingActivity*0.8)*100/10+max(0,(impatient-5)*10)+max(0,(worryTrait-5)*10)""}, ""emotionManager"": {""standard"": ""30|60"", ""result"": ""1|2|3"", ""formula"": ""100-(emotionalActivity*0.8+emotionalStress*1+anxietyTrait*1+delicateSensitive*1+midMoodWave*0.8+highMoodWave*0.8+innerHelplessness*1+innerResistance*1)*100/6+max(0,(emotionalStress-5)*10)+max(0,(anxietyTrait-5)*10)+max(0,(innerHelplessness-5)*5)+max(0,(innerResistance-5)*8)""}, ""easyObedient"": {""standard"": ""30|60"", ""result"": ""1|2|3"", ""formula"": ""100-(worry*1+worryTrait*1+delicateSensitive*1+midMoodWave*0.8+highMoodWave*0.8+innerHelplessness*1+innerResistance*1)*100/6+max(0,(worry-5)*20)+max(0,(worryTrait-5)*10)+max(0,(delicateSensitive-5)*10)""}, ""activeMind"": {""standard"": ""50|80"", ""result"": ""1|2|3"", ""formula"": ""(thinkingActivity*0.5+thinking*1.4+lowFlow*1.3+singleMindedness*1.8+mentalStress*4)*100/5+max(0,(thinking-5)*5)+max(0,(lowFlow-5)*8)+max(0,(singleMindedness-5)*10)+max(0,(mentalStress-5)*10)""}, ""fatigueStatus"": {""standard"": ""17|40|85|95"", ""result"": ""1|2|3|4|5"", ""formula"": ""(mentalFatigue*6+visualFatigue*6+lowDepress*6+midDepress*8+highDepress*10-lfn*0.1)*100/28+max(0,(mentalFatigue-5)*10)+max(0,(lowDepress-5)*10)+max(0,(midDepress-5)*10)+max(0,(highDepress-5)*10)""}, ""energyStatus"": {""standard"": ""50|80"", ""result"": ""1|2|3"", ""formula"": ""(lfn*0.2-mentalFatigue*2.5-visualFatigue*1+thinkingActivity*1.8+crisisSense*1.8+lowAnxiety*0.8+midAnxiety*1+ highAnxiety*1-lowDepress*1.2-midDepress*1.2-highDepress*1.5)*100/30 + max(0,(thinkingActivity-5)*3)+max(0,(crisisSense-5)*5)+max(0,(highAnxiety-5)*5) - max(0,(lowDepress-5)*10)""}, ""model_codes"": [""effortLevel"", ""focusOnInvestment"", ""enterprising"", ""emotionManager"", ""easyObedient"", ""activeMind"", ""fatigueStatus"", ""energyStatus""]}";

            string str4 = "{\"effortLevel\": {\"standard\": \"50|80\", \"result\": \"1|2|3\", \"formula\": \"(thinking*1+thinkingActivity*1+lowFlow*1+singleMindedness*1+lfn*0.15)*100/16+max(0,(thinking-5)*10)+max(0,(lowFlow-5)*10)+max(0,(singleMindedness-5)*10)\"}, \"focusOnInvestment\": {\"standard\": \"50|80\", \"result\": \"1|2|3\", \"formula\": \"(lowFlow*2.1+singleMindedness*2.3+midFlow*5+highFlow*8)*100/8+max(0,(singleMindedness-5)*10)\"}, \"enterprising\": {\"standard\": \"50|80\", \"result\": \"1|2|3\", \"formula\": \"(impatient*3.5+worryTrait*5+crisisSense*0.8+thinkingActivity*0.8)*100/10+max(0,(impatient-5)*10)+max(0,(worryTrait-5)*10)\"}, \"emotionManager\": {\"standard\": \"30|60\", \"result\": \"1|2|3\", \"formula\": \"100-(emotionalActivity*0.8+emotionalStress*1+anxietyTrait*1+delicateSensitive*1+midMoodWave*0.8+highMoodWave*0.8+innerHelplessness*1+innerResistance*1)*100/6+max(0,(emotionalStress-5)*10)+max(0,(anxietyTrait-5)*10)+max(0,(innerHelplessness-5)*5)+max(0,(innerResistance-5)*8)\"}, \"easyObedient\": {\"standard\": \"30|60\", \"result\": \"1|2|3\", \"formula\": \"100-(worry*1+worryTrait*1+delicateSensitive*1+midMoodWave*0.8+highMoodWave*0.8+innerHelplessness*1+innerResistance*1)*100/6+max(0,(worry-5)*20)+max(0,(worryTrait-5)*10)+max(0,(delicateSensitive-5)*10)\"}, \"activeMind\": {\"standard\": \"50|80\", \"result\": \"1|2|3\", \"formula\": \"(thinkingActivity*0.5+thinking*1.4+lowFlow*1.3+singleMindedness*1.8+mentalStress*4)*100/5+max(0,(thinking-5)*5)+max(0,(lowFlow-5)*8)+max(0,(singleMindedness-5)*10)+max(0,(mentalStress-5)*10)\"}, \"fatigueStatus\": {\"standard\": \"17|40|85|95\", \"result\": \"1|2|3|4|5\", \"formula\": \"(mentalFatigue*6+visualFatigue*6+lowDepress*6+midDepress*8+highDepress*10-lfn*0.1)*100/28+max(0,(mentalFatigue-5)*10)+max(0,(lowDepress-5)*10)+max(0,(midDepress-5)*10)+max(0,(highDepress-5)*10)\"}, \"energyStatus\": {\"standard\": \"50|80\", \"result\": \"1|2|3\", \"formula\": \"(lfn*0.2-mentalFatigue*2.5-visualFatigue*1+thinkingActivity*1.8+crisisSense*1.8+lowAnxiety*0.8+midAnxiety*1+ highAnxiety*1-lowDepress*1.2-midDepress*1.2-highDepress*1.5)*100/30 + max(0,(thinkingActivity-5)*3)+max(0,(crisisSense-5)*5)+max(0,(highAnxiety-5)*5) - max(0,(lowDepress-5)*10)\"}, \"model_codes\": [\"effortLevel\", \"focusOnInvestment\", \"enterprising\", \"emotionManager\", \"easyObedient\", \"activeMind\", \"fatigueStatus\", \"energyStatus\"]}";

            string str2 = @"{ ""lfnSet"": [60,60,60,60,60,60],""thinkingActivitySet"": [1,1,-1,-1,-1,-1],""thinkingSet"": [1,-1,-1,-1,-1,-1],""singleMindednessSet"": [1,1,-1,-1,1,-1],""highFlowSet"": [1,-1,-1,-1,-1,-1],""midFlowSet"": [1,-1,-1,-1,-1,-1],""lowFlowSet"": [1,-1,-1,-1,-1,-1],""highAnxietySet"": [1,1,-1,-1,1,-1],""midAnxietySet"": [1,1,-1,-1,1,-1],""lowAnxietySet"": [1,1,-1,-1,1,-1],""highDepressSet"": [1,1,-1,-1,1,-1],""midDepressSet"": [1,1,-1,-1,1,-1],""lowDepressSet"": [1,1,-1,-1,1,-1],""highMoodWaveSet"": [-1,-1,-1,-1,-1,-1],""midMoodWaveSet"": [-1,-1,-1,-1,-1,-1],""innerResistanceSet"": [-1,-1,-1,-1,-1,-1],""innerHelplessnessSet"": [-1,-1,-1,-1,-1,-1],""emotionalActivitySet"": [1,-1,-1,-1,-1,-1],""emotionalStressSet"": [-1,-1,1,-1,-1,-1],""mentalFatigueSet"": [-1,1,1,-1,1,-1],""visualFatigueSet"": [-1,1,1,-1,1,-1],""mentalStressSet"": [-1,-1,-1,-1,-1,-1],""anxietyTraitSet"": [-1,-1,-1,1,-1,-1],""delicateSensitiveSet"": [-1,-1,-1,-1,-1,-1],""impatientSet"": [-1,-1,-1,-1,-1,-1],""crisisSenseSet"": [-1,-1,-1,-1,-1,-1],""worrySet"": [1,1,0,1,0,1],""worryTraitSet"": [-1,-1,-1,-1,-1,-1],""drowsinessLevel"":[0],""sleepStage"":[1]}";
            string str3 = @"{""drowsinessLevel"":0,""sleepStage"":1}";
            string strConfig1 = @"{""analysisModels"":[""energyStatus"",""effortLevel"",""fatigueStatus"",""emotionManager"",""easyObedient"",""activeMind"",""focusOnInvestment"",""enterprising""],""statusCodes"":[""positive"",""serious"",""normal"",""common"",""relax"",""rest"",""-1""],""eventPointsUp"":[""difficult"",""detail"",""thinking"",""focus"",""downcast"",""nervous""],""eventPointsDown"":[""fatigue"",""helpless"",""worry"",""emotion"",""excite""]}";
            string str7 = @"{""adultEpilepsySet"":[0,0,0,0,0,0],""anginaSet"":[-2,-2,-2,-2,-2,-2],""highAnxietySet"":[-2,-2,-2,-2,-2,1],""midAnxietySet"":[-2,-2,-2,-2,-2,-1],""lowAnxietySet"":[-2,-2,-2,-2,-2,-1],""anxietyTraitSet"":[-2,-2,-2,-2,-2,-2],""bloodOxygenSet"":[0,0,0,0,0,0],""singleMindednessSet"":[-2,-2,-2,-2,-2,-2],""childrenEpilepsySet"":[0,0,0,0,0,0],""chronicPainSet"":[-2,-2,-2,-2,-2,-2],""mentalStressSet"":[-2,-2,-2,-2,-2,-2],""thinkingActivitySet"":[-2,-2,-2,-2,-2,-2],""coronaryAtherosclerosisSet"":[-2,-2,-2,-2,-2,-2],""coronaryDiseaseSet"":[-2,-2,-2,-2,-2,-2],""highCrossOutSet"":[-2,-2,-2,-2,-2,-2],""lowCrossOutSet"":[-2,-2,-2,-2,-2,-2],""highDepressSet"":[-2,-2,-2,-2,-2,-2],""midDepressSet"":[-2,-2,-2,-2,-2,-2],""lowDepressSet"":[-2,-2,-2,-2,-2,-2],""diabetesType1Set"":[-2,-2,-2,-2,-2,-2],""diabetesType2Set"":[-2,-2,-2,-2,-2,-2],""drunkSet"":[-2,-2,-2,-2,-2,-2],""drunk2Set"":[-2,-2,-2,-2,-2,-2],""emotionalStressSet"":[-2,-2,-2,-2,-2,-2],""emotionalActivitySet"":[-2,-2,-2,-2,-2,-2],""erectileDysfunctionSet"":[0,0,0,0,0,0],""essentialHypertensionSet"":[-2,-2,-2,-2,-2,-2],""midFeverSet"":[-2,-2,-2,-2,-2,-2],""lowFeverSet"":[-2,-2,-2,-2,-2,-2],""highFlowSet"":[-2,-2,-2,-2,-2,-2],""midFlowSet"":[-2,-2,-2,-2,-2,-2],""lowFlowSet"":[-2,-2,-2,-2,-2,-2],""heartFailureSet"":[-2,-2,-2,-2,-2,-2],""heartRateTenAvgSet"":[78,83,83,82,85,84],""highHeroinAddictionSet"":[-1,-1,-1,-1,-1,-1],""lowHeroinAddictionSet"":[-1,-1,-1,-1,-1,-1],""thinkingSet"":[-1,-1,-1,-1,-1,-1],""highMoodWaveSet"":[-1,-1,-1,-1,-1,-1],""midMoodWaveSet"":[-1,-1,-1,-1,-1,-1],""lfnSet"":[31,30,38,55,64,77],""lfnAvgSet"":[35,33,35,39,43,48],""meanRateSet"":[78,77,77,80,81,83],""mentalFatigueSet"":[-2,-2,-2,-2,-2,-1],""delicateSensitiveSet"":[-2,-2,-2,-2,-2,-2],""nocturnalHypoglycemiaSet"":[0,0,0,0,0,0],""onLineGameAddictionSet"":[-2,-2,-2,-2,-2,-2],""ruminationSet"":[-2,-2,-2,-2,-2,-2],""highShiYingLevelSet"":[-1,-1,-1,-1,-1,-1],""midShiYingLevelSet"":[-1,-1,-1,-1,-1,-1],""lowShiYingLevelSet"":[-1,-1,-1,-1,-1,-1],""stimPainSet"":[-2,-2,-2,-2,1,1],""strokeSet"":[-2,-2,-2,-2,-2,-2],""suddenCardiacDeathSet"":[-2,-2,-2,-2,-2,-2],""impatientSet"":[-2,-2,-2,-2,-2,-2],""crisisSenseSet"":[-2,-2,-2,-2,-2,-2],""visualFatigueSet"":[-2,-2,-1,-1,-1,-1],""worrySet"":[-2,-2,-2,-2,-2,-2],""worryTraitSet"":[-2,-2,-2,-2,-2,-2],""innerResistanceSet"":[-1,-1,-1,-1,-1,-1],""innerHelplessnessSet"":[-1,-1,-1,-1,-1,-1],""sleepStage"":[4],""drowsinessLevel"":[0]}";


            string str5 = "{\"standard\": \"50|80\"}";
            str1 = str1.Replace("\"", "\\\"");   //将单引号(") 变成(\")
            str2 = str2.Replace("\"", "\\\"");
            strConfig1 = strConfig1.Replace("\"", "\\\"");

            str7 = str7.Replace("\"", "\\\"");


            string str6="yyry554";

            //evaluator.Evaluate($"ScriptDemo.OneMinuteAnalysis2(\"{str4}\")", out result, out _);
            evaluator.Evaluate($"ScriptOne.ConfigureParas(\"{strConfig1}\",\"{str1}\")", out result2, out _);
           

            evaluator.Evaluate($"ScriptOne.OneMinuteAnalysis(\"{str7}\")", out result, out _);
            // evaluator.Evaluate($"ScriptDemo.OneMinuteAnalysis({str4},{str4}\",\"{str4}\")", out result, out _);
            //   evaluator.Evaluate($"new Script().Sum(3,4)", out result, out _);
            Console.WriteLine($"run code dynamic. time: {watch.Elapsed}, result: {result}");

            lblText.Text = result.ToString();

            watch.Stop();
            watch = null;


        }
    }
   
}

